﻿using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using TianShu.LicenseAuthorizer.Abstracts.Config;
using TianShu.Untils.Encrypt;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
using Volo.Abp.Timing;

namespace TianShu.LicenseAuthorizer.Abstracts.Service
{
    public class NullLiceseLoaderService : ILiceseLoaderService, ISingletonDependency
    {

        private static IDictionary<string, LicenseAuthorizerDto> _licenseAuthorizerDic = new ConcurrentDictionary<string, LicenseAuthorizerDto>();

        private readonly LicenseLoaderOptions _licenseLoaderOptions;
        private readonly IRsaEncrypt _rsaEncrypt;
        private readonly IJsonSerializer _jsonSerializer;
        private readonly IClock _clock;

        public NullLiceseLoaderService(IOptions<LicenseLoaderOptions> options, IRsaEncrypt rsaEncrypt, IJsonSerializer jsonSerializer, IClock clock)
        {
            this._licenseLoaderOptions = options.Value;
            this._rsaEncrypt = rsaEncrypt;
            this._jsonSerializer = jsonSerializer;
            this._clock = clock;
        }

        public IDictionary<string, LicenseAuthorizerDto> GetAllLicenseAuthorizerInfo()
        {
            if (_licenseAuthorizerDic.Count > 0)
            {
                return _licenseAuthorizerDic;
            }

            LoadLicenseFiles();

            return _licenseAuthorizerDic;
        }

        public LicenseAuthorizerDto CheckLicenseAuthorizer(Guid? tenantId, string appKey)
        {
            if (tenantId == null)
            {
                return null;
            }
            var key = $"{tenantId}_{appKey}".ToLower();
            if (_licenseAuthorizerDic.ContainsKey(key) == false)
            {
                throw new UserFriendlyException($"license非法,【{key}】");
            }
            var licenseAuthorizer = _licenseAuthorizerDic[key];
            var nowTime = _clock.Now;
            if (nowTime < licenseAuthorizer.StartTime || nowTime > licenseAuthorizer.EndTime)
            {
                throw new UserFriendlyException("license授权过期，清联系管理员");
            }
            return licenseAuthorizer;
        }

        public void AddLicense(Stream licenseFile)
        {
            using (licenseFile)
            {

                using StreamReader reader = new StreamReader(licenseFile);
                var fileContext = reader.ReadToEnd();
                LicenseAuthorizerDto licenseInfo = null;
                try
                {

                    var jsonStr = _rsaEncrypt.PublicKeyDecrypt(LiceseAuthorizerConst.DecryptKey, fileContext);
                    licenseInfo = _jsonSerializer.Deserialize<LicenseAuthorizerDto>(jsonStr);
                }
                catch (Exception ex)
                {
                    throw new UserFriendlyException($"license文件非法");
                }
                if (LiceseAuthorizerConst.GetMACIp() != licenseInfo.MachineInfo)
                {
                    throw new UserFriendlyException($"该license不属于该电脑");
                }
                var nowTime = _clock.Now;
                if (nowTime < licenseInfo.StartTime || nowTime > licenseInfo.EndTime)
                {
                    throw new UserFriendlyException($"license授权已过期，或不在时间范围内");
                }
                _licenseAuthorizerDic[$"{licenseInfo.CustomerId}_{licenseInfo.AppKey}".ToLower()] = licenseInfo;

                var saveDir = _licenseLoaderOptions.GetAllAbsoultDirList().First();
                var fileSavePath = Path.Combine(saveDir,$"{licenseInfo.CustomerCode}_{licenseInfo.AppKey}_{licenseInfo.MachineInfo.ToMd5()}.txt");

                licenseFile.Position = 0;
                licenseFile.SaveFile(fileSavePath);

            }
        }

        private void LoadLicenseFiles()
        {
            foreach (var item in _licenseLoaderOptions.GetAllAbsoultDirList())
            {
                foreach (var filePathItem in Directory.GetFiles(item))
                {
                    var fileContext = File.ReadAllText(filePathItem);
                    var jsonStr = _rsaEncrypt.PublicKeyDecrypt(LiceseAuthorizerConst.DecryptKey, fileContext);
                    var licenseInfo = _jsonSerializer.Deserialize<LicenseAuthorizerDto>(jsonStr);
                    if (LiceseAuthorizerConst.GetMACIp() != licenseInfo.MachineInfo)
                    {
                        throw new UserFriendlyException($"存在不属于该电脑的license，【{filePathItem}】");
                    }
                    //var nowTime = _clock.Now;
                    //if (nowTime < licenseInfo.StartTime || nowTime > licenseInfo.EndTime)
                    //{
                    //    throw new UserFriendlyException($"存在过期的license授权【{filePathItem}】，请删除");
                    //}
                    _licenseAuthorizerDic[$"{licenseInfo.CustomerId}_{licenseInfo.AppKey}".ToLower()] = licenseInfo;
                }
            }
            if (_licenseAuthorizerDic.Count < 1)
            {
                throw new UserFriendlyException($"缺少license文件");
            }
        }
    }
}
